package injection;

import domain.User;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.xml.XmlBeanDefinitionReader;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Configuration;

import javax.inject.Inject;
import java.util.Collection;
import java.util.Optional;

/**
 * 注解驱动的依赖注入过程<p>
 * {@link org.springframework.beans.factory.support.DefaultListableBeanFactory#resolveDependency}<p>
 * 同一个类每注入一个依赖，都需要调用一次 resolveDependency()
 * @author jackcfan
 * @date 2021/9/15
 */
@Configuration
public class AnnotationDependencyResolutionTest {
    /**
     * DependencyDescriptor 依赖描述对象:
     *      // 容器类，即当前类
     *      declaringClass = {Class@699} "class injection.AnnotationResolutionTest"
     *
     *      // 当前类注入的是 user 属性
     *      fieldName = "user"
     *
     *      required = true
     *      eager = true
     *      nestingLevel = 1
     *
     *      // 包含类，cglib代理对象
     *      containingClass = {Class@1983} "class injection.AnnotationResolutionTest$$EnhancerBySpringCGLIB$$6dec78be"
     *
     *      // 依赖的字段
     *      field = {Field@2448} "domain.User injection.AnnotationResolutionTest.user"
     *      fieldAnnotations = null
     * */
    @Autowired
    User user;  // 实时注入，通过类型(User.class)依赖查找 + 字段名称("user)

    /**
     * declaringClass = {Class@699} "class injection.AnnotationDependencyResolutionTest"
     *      declaringClass = {Class@699} "class injection.AnnotationDependencyResolutionTest"
     *      fieldName = "users"
     *      required = true
     *      eager = true
     *      nestingLevel = 1
     *      containingClass = {Class@1983} "class injection.AnnotationDependencyResolutionTest$$EnhancerBySpringCGLIB$$6329a7c9"
     *      field = {Field@2573} "java.util.Collection injection.AnnotationDependencyResolutionTest.users"
     * */
    @Autowired
    Collection<User> users; // 注入集合：User、SuperUser

    /**
     * Optional jkd 容器对象，本质上是一个包装器类
     * */
    @Autowired
    Optional<User> optionalUser;

    /**
     * JSR 303 API
     * */
    @Inject
    User injectedUser;

    @Test
    public void test(){
        // 注解 + xml 配置文件
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        // 1.注册注解 Bean
        applicationContext.register(this.getClass());

        // 2.读取 xml 配置文件
        // AnnotationConfigApplicationContext 实现了注册中心接口
        // XmlBeanDefinitionReader(BeanDefinitionRegistry registry)
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(applicationContext);

        // 加载 xml 资源，解析并生成 BeanDefinition
        beanDefinitionReader.loadBeanDefinitions("dependency-setter-injection.xml");

        applicationContext.refresh();

        AnnotationDependencyResolutionTest resolution = applicationContext.getBean(AnnotationDependencyResolutionTest.class);

        System.out.println("user:"+resolution.user);

        applicationContext.close();
    }
}
